package com.yet.container.remote.netty.client;

import org.apache.commons.pool2.impl.GenericObjectPool;

import com.yet.container.registry.RegistryMeta.Address;
import com.yet.serialization.Serialization;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public class NettyClientPool {

	private static final ConcurrentHashMap<Address, NettyClientPool> clientPools = new ConcurrentHashMap<>();

	private GenericObjectPool<NettyClient> pool;

	private int maxTotal = 2;

	public NettyClientPool(Address address, Serialization serialization) {
		pool = new GenericObjectPool<NettyClient>(new NettyClientPoolFactory(address, serialization));
		pool.setTestOnBorrow(true);
		pool.setMaxTotal(maxTotal);
	}

	public GenericObjectPool<NettyClient> getPool() {
		return this.pool;
	}

	public boolean needWait() {
		return pool.getBorrowedCount() < maxTotal;
	}

	public static NettyClientPool getClientPool(Address address, Serialization serialization) throws Exception {
		return clientPools.computeIfAbsent(address, k->new NettyClientPool(address, serialization));
	}

	/**
	 * 判断是否已经有空闲的连接，有则返回，无则返回null
	 * 
	 * @param addresses
	 *            List
	 * @return NettyClientPool or null
	 */
	public static NettyClientPool getClientPoolExistAndNoWaiters(List<Address> addresses) {
		return addresses.stream().map(a -> clientPools.get(a)).filter(p -> p != null).filter(p -> p.needWait())
				.findAny().orElse(null);
	}

	public static void close() {
		clientPools.values().forEach(p -> {
			p.getPool().close();
		});
	}

	public int getMaxTotal() {
		return maxTotal;
	}

	public void setMaxTotal(int maxTotal) {
		this.maxTotal = maxTotal;
	}

}
